

#pragma once

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <stdexcept>
#include <assert.h>


#include "IniKeyValue.h"
#include "IniSection.h"
  

#pragma warning(push)
#pragma warning( disable : 4290 )

//! \brief  Read/write  from/to ini-file.  
namespace ksini 
{
 
  //---------------------------------------------------------------




//! \brief  main class.
class IniFile  {
public:
		 IniFile() {}
		
		~IniFile() 
		{ 
			m_vector_sections.clear(); 
		}

 
bool searchSection(  int& index, const std::string& sSection) const;
bool isSectionExists(const std::string& sSection) const;

int getNumSections() const 
{ 
	return (int)m_vector_sections.size(); 
}

IniSection&        getSectionByIndex(const int index) throw(std::runtime_error&);
const IniSection&  getSectionByIndex(const int index) const throw(std::runtime_error&);

IniSection* addSection(const std::string& sSection, const std::string& commentLine="");

//! \brief Полностью удалить все секции с ключами .
void clear_all() 
{ 
	m_vector_sections.clear(); 
}

//! \brief считать из строки   ini-данные .
bool read_from_string(const std::string& src);

//! \brief записать в строку   ini-данные  .
bool write_to_string(  std::string& dest) const;


//! \brief прочитать  ini-файл .
bool load_from_file(const std::string& fname);

//! \brief  записать в ini-файл .
bool save_to_file(const std::string& fname) const;

//! \brief прочитать  ini-файл (wstring).
bool load_from_file(const std::wstring& fname);

//! \brief  записать в ini-файл (wstring).
bool save_to_file(const std::wstring& fname) const;





/*
 исключены для unicode так как только для windows

bool ReadFromFileW(const WCHAR* fname); 
bool WriteToFileW(const WCHAR* fname) const;  
*/
	

void set_value(const std::string& sSection, 
			  const std::string& sKey, 
			  const std::string& value,
			  const char* comment="") throw  (std::runtime_error);

std::string get_value(const std::string& sSection, 
					  const std::string& sKey, 
					  const std::string& default_value = "" ) throw  (std::runtime_error);


 
void set_bool( const std::string& sSection, 
			   const std::string& sKey, 
			   const bool value,
			   const char* comment="");


bool get_bool( const std::string& sSection, 
			   const std::string& sKey, 
			   bool default_value);


void set_int(  const std::string& sSection, 
			   const std::string& sKey, 
			   const int value,
			   const char* comment="");


int get_int(   const std::string& sSection, 
			   const std::string& sKey, 
			   const int default_value) ;


void set_float( const std::string& sSection, 
			    const std::string& sKey, 
				const float value,
				const char* comment="");


float get_float( const std::string& sSection, 
				 const std::string& sKey, 
				 const float default_value) ;
 
friend std::ostream& operator << (std::ostream&os, const IniFile& _ini) 
{  
	std::string str;
	_ini.write_to_string(str);
	os << str << "\n";
	return os;
}



private:

	 

	bool parseKeyValueString( std::string& s_OutKey, 
							  std::string& s_OutValue,
							  const std::string& src ) const ;


	std::vector<IniSection> m_vector_sections;
	
};
 


}
 
#pragma warning(pop)
 
